﻿using com.uplus.log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace WebApi.Common
{
    public class TcpServerHelper
    {
        public static AsyncTcpServer server;
        public static Dictionary<string, TcpClient> pairs = new Dictionary<string, TcpClient>();
        static Dictionary<string, TcpClient> pairsClient = new Dictionary<string, TcpClient>();//测试工具客户端Tcp缓存
        public delegate void RecevieRelayReplyDataHandler(object sender, string dtuId, string data);
        public event RecevieRelayReplyDataHandler RecevieRelayReplyData;

        public TcpServerHelper(int port)
        {
            server = new AsyncTcpServer(port);//3657 有人    502 康耐德
            server.Encoding = Encoding.UTF8;
            server.ClientConnected += new EventHandler<TcpClientConnectedEventArgs>(Server_ClientConnected);
            server.ClientDisconnected += new EventHandler<TcpClientDisconnectedEventArgs>(Server_ClientDisconnected);
            server.DatagramReceived += new EventHandler<TcpDatagramReceivedEventArgs<byte[]>>(Server_DatagramReceived);
            tcpServerHelper = this;

        }


        public static TcpServerHelper tcpServerHelper
        {
            get;
            set;
        }

        #region 方法
        public void Start()

        {
            if (server != null)
            {
                server.Start();
                pairs.Clear();
                pairsClient.Clear();
            }
        }

        /// <summary>
        /// 给指定DTU设备发送指令
        /// </summary>
        /// <param name="dtuId">DTU设备的ID</param>
        /// <param name="mess">要发送的开关控制器的命令</param>
        public void SendMess(string dtuId, int line, byte[] mess)
        {
            if (server != null && pairs.ContainsKey(dtuId))
            {
                server.Send(pairs[dtuId], mess);
                Log4Helper.Debug(this.GetType(), $"{DateTime.Now} 对{dtuId}的开关{line}发送命令");
                RecevieRelayReplyData += TcpServerHelper_RecevieRelayReplyData1;
            }
        }

        private void TcpServerHelper_RecevieRelayReplyData1(object sender, string dtuId, string data)
        {
            try
            {
                Log4Helper.Debug(this.GetType(), $"{DateTime.Now}接收到对{dtuId}的命令，数据为{data}");

            }
            catch
            {

            }
        }
        #endregion

        #region  事件
        private void Server_DatagramReceived(object sender, TcpDatagramReceivedEventArgs<byte[]> e)
        {
            lock (this)
            {
                try
                {
                    TcpClient tcpClient = e.TcpClient;
                    string msg = "";
                    string start = "";
                    //3657 有人    502 康耐德
                    string port = tcpClient.Client.LocalEndPoint.ToString().Split(':')[1];
                   
                    if (port == "3657")
                    {
                        msg = Encoding.Default.GetString(e.Datagram);
                        start = msg.Substring(0, 2);
                    }
                    if (port == "8080")
                    {
                        msg = Encoding.Default.GetString(e.Datagram);
                        if (!string.IsNullOrEmpty(msg) && msg.Contains("vgdecoderesult=") && msg.Contains("devicenumber=") && msg.Contains("otherparams="))
                        {
                            msg = msg.Replace("vgdecoderesult=", "").Replace("&devicenumber=", "").Replace("&otherparams=", "");
                            //AccessControlQRDate qRDate = new AccessControlQRDate();
                            //qRDate.vgdecoderesult = msg.Split('&')[0];
                            //qRDate.devicenumber = msg.Split('&')[1];
                            //qRDate.otherparams = msg.Split('&')[2];
                            //AccessControlModel controlModel = BizBase.Get<BizAccessControl>().GetModelByDeviceCode(qRDate.devicenumber);
                            //if (controlModel != null)
                            //{
                            //    if (BizBase.Get<BizAccessControl>().CheckUserAccess(qRDate.vgdecoderesult, controlModel.FkSelfCompany, qRDate.devicenumber))
                            //    {
                            //        TcpServerHelper.server.Send(tcpClient, "code=0000");
                            //    }
                            //    else
                            //    {
                            //        Log4Helper.Debug(this.GetType(), $"{ qRDate.vgdecoderesult}无权访问，该设备{qRDate.devicenumber}");
                            //    }
                            //}

                            //if (qRDate != null)
                            //{

                            //    //byte[] res = DataConvert.ToBytes("code=0000");
                            //    //byte[] res = System.Text.Encoding.Default.GetBytes();
                            //    //TcpServerHelper.server.Send(tcpClient, "code=0000");
                            //}
                        }
                        else
                        {
                            //AccessControlModel controlModel = BizBase.Get<BizAccessControl>().GetModelByDeviceCode(msg);
                            //if (controlModel != null)
                            //{
                            //    controlModel.TRequest = DateTime.Now;
                            //    BizBase.Get<BizAccessControl>().Update(controlModel);
                            //}
                        }
                        //start = msg.Substring(0, 2);
                    }
                    Log4Helper.Info("接收数据", msg);
                    if (pairs.Count > 0)
                    {
                        foreach (var item in pairs)
                        {
                            Log4Helper.Info(this.GetType(), $"自定义注册包key：{item.Key}，value:{item.Value}");
                        }
                    }

                }
                catch (Exception ex)
                {
                    Log4Helper.Error(this.GetType(), $"TcpServer接收数据异常{ ex.Message}");
                    Start();
                }
            }

        }

        /*private void Server_DatagramReceived(object sender, TcpDatagramReceivedEventArgs<byte[]> e)
        {
            lock (this)
            {
                try
                {
                    TcpClient tcpClient = e.TcpClient;

                    string msg = DataConvert.ToHexString(e.Datagram);
                    Log4Helper.Info("接收数据", msg);
                    string start = msg.Substring(0, 2);
                    if (pairs.Count > 0)
                    {
                        foreach (var item in pairs)
                        {
                            Log4Helper.Info(this.GetType(), $"自定义注册包key：{item.Key}，value:{item.Value}");
                        }
                    }

                    switch (start)
                    {
                        //测试工具客户端发来的数据
                        case "SS":

                            break;
                        //处理控制器心跳数据
                        case "DR":
                            if (!pairs.ContainsValue(tcpClient))
                            {
                                string key = msg;
                                if (pairs.ContainsKey(key))
                                {
                                    pairs.Remove(key);
                                }
                                pairs.Add(key, tcpClient);
                                Log4Helper.Debug(this.GetType(), $"控制器发来心跳包数据，同时将控制器加入到Tcp池中，控制器Id={key}");
                                Log4Helper.Info(this.GetType(), $"控制器发来心跳包数据，同时将控制器加入到Tcp池中，控制器Id={msg.Substring(2)}");
                            }
                            break;
                        //处理回复数据
                        case "DD":
                            string info = msg.Substring(2, 8);
                            string[] str = info.Split('|');
                            //EquipmentModel equipmentModel = BizBase.Get<BizEquipment>().Get(str[0]);
                            SwitchModel switchModel = BizBase.Get<BizSwitch>().GetByWay(str[0], Convert.ToInt32(str[1]));


                            //第一种情况:如果测试工具客户端存在，则给测试工具客户端发送控制器回复的数据
                            switch (str[2])
                            {
                                case "1":
                                    if (pairs.ContainsKey(switchModel.SRegisterBagCode))
                                    {
                                        byte[] res = strTo16(switchModel.SOpenCommand.Trim());
                                        server.Send(pairs[switchModel.SRegisterBagCode], res);//DataConvert.ToDigitsBytes(switchModel.SOpenCommand.Trim()));

                                    }
                                    break;
                                case "2":
                                    if (pairs.ContainsKey(switchModel.SRegisterBagCode))
                                    {
                                        byte[] res = strTo16(switchModel.SOffCommand.Trim());
                                        server.Send(pairs[switchModel.SRegisterBagCode], res);

                                    }
                                    break;
                            }

                            break;

                        case "DT":

                            string lastLetter = msg.Substring(msg.Length - 1, 1);
                            StringBuilder sb = new StringBuilder(msg.Substring(2, msg.Length - 3));
                            byte[] array = new byte[1];
                            array = Encoding.ASCII.GetBytes(lastLetter); //把str的每个字符转换成ascii码
                            sb.Append("|").Append(array[0] - 64);
                            foreach (var item in pairs)
                            {
                                server.Send(pairs[item.Key], sb.ToString());
                            }

                            break;

                    }
                }
                catch (Exception ex)
                {
                    Log4Helper.Error(this.GetType(), $"TcpServer接收数据异常{ ex.Message}");
                    Start();
                }
            }

        }*/


        public byte[] strTo16(string s)
        {
            try
            {
                string[] strArr = s.Trim().Split(' ');
                byte[] b = new byte[strArr.Length];
                //逐个字符变为16进制字节数据
                for (int i = 0; i < strArr.Length; i++)
                {
                    b[i] = Convert.ToByte(strArr[i], 16);
                }
                return b;
            }
            catch (Exception ex)
            {
                Log4Helper.Error(this.GetType(), "", ex);
                return null;

            }
            //按照指定编码将字节数组变为字符串
        }


        private void Send(string msg, Socket socket)
        {
            byte[] buffer = Encoding.Default.GetBytes(msg);
            socket.Send(buffer);
        }


        private void TcpServerHelper_RecevieRelayReplyData(object sender, string dtuId, string data)
        {

            Log4Helper.Info(this.GetType(), $"help时间结束代码，{data}");

        }

        private void Server_ClientConnected(object sender, TcpClientConnectedEventArgs e)
        {
            //zt start
            TcpClient tcpClient = e.TcpClient;
            string port = tcpClient.Client.LocalEndPoint.ToString().Split(':')[1];
            if (port == "502")
            {

            }
            if (port == "3657")
            {
            }
            //zt end
        }
        private void Server_ClientDisconnected(object sender, TcpClientDisconnectedEventArgs e)
        {
            if (pairs.Values.Contains(e.TcpClient))
            {
                string key = pairs.FirstOrDefault(p => p.Value == e.TcpClient).Key;
                pairs.Remove(key);
                Log4Helper.Info(this.GetType(), $"控制器{key}断开Tcp连接");
            }

            if (pairsClient.Values.Contains(e.TcpClient))
            {
                string key = pairsClient.FirstOrDefault(p => p.Value == e.TcpClient).Key;
                pairsClient.Remove(key);
                Log4Helper.Info(this.GetType(), $"测试工具客户端{key}断开Tcp连接");
            }

            //zt start
            TcpClient tcpClient = e.TcpClient;
            string port = tcpClient.Client.LocalEndPoint.ToString().Split(':')[1];
            if (port == "502")
            {
            }
            if (port == "3657")
            {
            }
            //zt end
        }
        #endregion
    }
}
